﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Uiap.Infrastructure.Runtime.Caching
{
    /// <summary>
    /// 缓存管理器扩展
    /// </summary>
    public static class CacheManagerExtension
    {
        /// <summary>
        /// 获取缓存值，如果缓存中不存在此Key对应的对象
        /// 则执行加载操作，然后加入缓存再返回（默认缓存过期时间为60秒）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="cacheManager">缓存管理器</param>
        /// <param name="key">缓存唯一标识Key</param>
        /// <param name="acquire">缓存不存在时执行的方法</param>
        /// <returns>缓存对象</returns>
        public static T Get<T>(this ICacheManager cacheManager, string key, Func<T> acquire)
        {
            return Get(cacheManager, key, 60, acquire);
        }

        /// <summary>
        /// 获取缓存值，如果缓存中不存在此Key对应的对象
        /// 则执行加载操作，然后加入缓存再返回
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="cacheManager">缓存管理器</param>
        /// <param name="key">缓存唯一标识Key</param>
        /// <param name="cacheTime">缓存过期时间(s)</param>
        /// <param name="acquire">缓存不存在时执行的方法</param>
        /// <returns>缓存对象</returns>
        public static T Get<T>(this ICacheManager cacheManager, string key, int cacheTime, Func<T> acquire)
        {
            var model = cacheManager.Get<T>(key);
            if (!EqualityComparer<T>.Default.Equals(model, default(T)))
            {
                return model;
            }

            var result = acquire();
            if (cacheTime > 0 && !EqualityComparer<T>.Default.Equals(result, default(T)))
                cacheManager.Set(key, result, cacheTime);
            return result;
        }

        /// <summary>
        /// 获取缓存值，如果缓存中不存在此Key对应的对象
        /// 则执行加载操作，然后加入缓存再返回
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="cacheManager">缓存管理器</param>
        /// <param name="key">缓存唯一标识Key</param>
        /// <param name="cacheTime">缓存过期时间(s)</param>
        /// <param name="acquire">缓存不存在时执行的方法</param>
        /// <returns>缓存对象</returns>
        public static async Task<T> GetAsync<T>(this ICacheManager cacheManager, string key, int cacheTime, Func<Task<T>> acquire)
        {
            var model = cacheManager.Get<T>(key);
            if (!EqualityComparer<T>.Default.Equals(model, default(T)))
            {
                return model;
            }

            var result = await acquire();
            if (cacheTime > 0 && !EqualityComparer<T>.Default.Equals(result, default(T)))
                cacheManager.Set(key, result, cacheTime);
            return result;
        }

        /// <summary>
        /// 根据匹配模式移除缓存项
        /// </summary>
        /// <param name="cacheManager">缓存管理器</param>
        /// <param name="pattern">匹配模式</param>
        /// <param name="keys">缓存中的所有key</param>
        public static void RemoveByPattern(this ICacheManager cacheManager, string pattern, IEnumerable<string> keys)
        {
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            foreach (var key in keys.Where(p => regex.IsMatch(p.ToString())).ToList())
                cacheManager.Remove(key);
        }
    }
}
